import { deviceTreeControllerDeviceTree as getTreeList } from '@/services/ess/deviceTree';
import { stationAreaControllerImplDeleteStationArea as delArea } from '@/services/ess/stationArea';
import { stationSelfDeviceControllerImplDeleteStationDevice as delDevice } from '@/services/ess/stationDevice';
import { SearchOutlined } from '@ant-design/icons';
import { useIntl, useModel } from '@umijs/max';
import { Button, Input, message, Modal, Tree } from 'antd';
import type { DataNode, EventDataNode } from 'antd/es/tree';
import { debounce } from 'lodash';
import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import styles from '../index.less';
import AddAreaModal from './AddAreaModal';
import AddModal from './AddModal';

interface TreeProps {
  handleClick?: (deviceId: any, treeData: any, deviceType: string | null, areaId?: string) => void;
  deleteCall?: () => void;
}

interface TreeNode extends EventDataNode<DataNode> {
  deviceId: string;
  deviceName: string;
  deviceType: string | null;
  areaId?: string;
  subDevices?: TreeNode[];
}

const TreeList = forwardRef(({ handleClick, deleteCall }: TreeProps, ref: any) => {
  const [treeData, setTreeData] = useState<TreeNode[]>([]);
  const [treeALL, setTreeALL] = useState<TreeNode[]>([]);
  const [selectNodeID, setSelectNodeID] = useState<string>('');
  const [selectNodeType, setSelectNodeType] = useState<string | null>(null);
  const [selectNodeDeviceId, setSelectNodeDeviceId] = useState<string>('');
  const [selectNodeAreaId, setSelectNodeAreaId] = useState<string | undefined>(undefined); // 新增
  const [isRootNode, setIsRootNode] = useState<boolean>(false);
  const [treeSubDevices, setTreeSubDevices] = useState();
  const [, setDeviceName] = useState<string>('');
  const { confirm } = Modal;
  const intl = useIntl();
  const { isArea } = useModel('@@initialState')?.initialState;
  const [hasArea, setHasArea] = useState<boolean>(false);
  const [hasDevice, setHasDevice] = useState<boolean>(false);

  const addUniqueKeyToNodes = (nodes: TreeNode[], prefix = 'node_'): TreeNode[] => {
    return nodes.map((node, index) => {
      const newNode: TreeNode = {
        ...node,
        key: `${prefix}${node.deviceId}_${index}`,
      };
      if (newNode.subDevices) {
        newNode.subDevices = addUniqueKeyToNodes(newNode.subDevices, `${newNode.key}_`);
      }
      return newNode;
    });
  };

  const checkSiteStatus = (
    treeSubDevices: TreeNode[],
  ): { hasArea: boolean; hasDevice: boolean } => {
    let hasArea = false;
    let hasDevice = false;

    const traverseNodes = (nodes: TreeNode[]) => {
      for (const node of nodes) {
        if (node.deviceType === 'AREA') {
          hasArea = true;
        } else {
          hasDevice = true;
        }
        if (node.subDevices) {
          traverseNodes(node.subDevices);
        }
      }
    };

    traverseNodes(treeSubDevices);
    return { hasArea, hasDevice };
  };

  const queryTreeList = async () => {
    let result: any = await getTreeList({ treeLevel: isArea ? '3' : '2', needGroupNode: 'false' });
    if (result && result.success) {
      setTreeSubDevices(result.data.subDevices);
      const wrappedData = addUniqueKeyToNodes([result.data]);
      setTreeData(wrappedData);
      setTreeALL(wrappedData);
      if (wrappedData.length > 0) {
        setSelectNodeID(wrappedData[0].key as string);
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        handleClick &&
          handleClick(
            wrappedData[0].deviceId,
            wrappedData,
            wrappedData[0].deviceType,
            wrappedData[0].areaId,
          );
        // 设置根节点状态
        setIsRootNode(true);
      }

      const { hasArea, hasDevice } = checkSiteStatus(result.data.subDevices);
      setHasArea(hasArea);
      setHasDevice(hasDevice);
    }
  };

  useImperativeHandle(ref, () => ({
    queryTreeList: () => {
      queryTreeList();
    },
  }));

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    setDeviceName(value);

    const filterTreeData = (nodes: TreeNode[], keyword: string): TreeNode[] => {
      return nodes
        .map((node): TreeNode | null => {
          if (node.deviceName.includes(keyword)) {
            return node;
          }
          if (node.subDevices) {
            const filteredSubDevices: TreeNode[] = filterTreeData(node.subDevices, keyword);
            if (filteredSubDevices.length > 0) {
              return { ...node, subDevices: filteredSubDevices };
            }
          }
          return null;
        })
        .filter((node): node is TreeNode => node !== null);
    };

    const filteredData = filterTreeData(treeALL, value);
    setTreeData(filteredData);
  };

  const findNodeByKey = (key: string, nodes: TreeNode[]): TreeNode | null => {
    for (const node of nodes) {
      if (node.key === key) {
        return node;
      }
      if (node.subDevices) {
        const found = findNodeByKey(key, node.subDevices);
        if (found) {
          return found;
        }
      }
    }
    return null;
  };

  const DeleteTree = async () => {
    if (selectNodeType !== null && selectNodeType !== 'AREA') {
      confirm({
        title: intl.formatMessage({ id: 'global.prompt' }),
        content: intl.formatMessage({ id: 'global.delTip' }),
        onOk: async () => {
          try {
            const res = await delDevice({ device_id: selectNodeDeviceId });
            if (res.success === true) {
              message.success(intl.formatMessage({ id: 'global.delSuccess' }));
              queryTreeList();
              // eslint-disable-next-line @typescript-eslint/no-unused-expressions
              deleteCall && deleteCall();
            }
          } catch (error) {
            message.error(intl.formatMessage({ id: 'global.delFail' }));
          }
        },
        onCancel() {},
      });
    } else {
      const selectedNode = findNodeByKey(selectNodeID, treeData);
      if (selectedNode && selectedNode.subDevices && selectedNode.subDevices.length > 0) {
        message.info(intl.formatMessage({ id: 'siteManage.delAreaTip' }));
        return;
      }
      confirm({
        title: intl.formatMessage({ id: 'global.prompt' }),
        content: intl.formatMessage({ id: 'global.delTip' }),
        onOk: async () => {
          try {
            // @ts-ignore
            await delArea({ area_id: selectNodeAreaId });
            message.success(intl.formatMessage({ id: 'global.delSuccess' }));
            queryTreeList();
            // eslint-disable-next-line @typescript-eslint/no-unused-expressions
            deleteCall && deleteCall();
          } catch (error) {
            message.error(intl.formatMessage({ id: 'global.delFail' }));
          }
        },
        onCancel() {},
      });
    }
  };

  const TreeSelectMethod = (
    selectedKeys: React.Key[],
    info: {
      event: 'select';
      selected: boolean;
      node: EventDataNode<TreeNode>;
      selectedNodes: TreeNode[];
      nativeEvent: MouseEvent;
    },
  ) => {
    if (selectedKeys.length === 0) {
      return;
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-expressions
    handleClick && handleClick(info.node.deviceId, treeALL, info.node.deviceType, info.node.areaId);
    setSelectNodeID(info.node.key as string);
    setSelectNodeType(info.node.deviceType);
    setSelectNodeDeviceId(info.node.deviceId);
    setSelectNodeAreaId(info.node.areaId); // 新增
    // 判断是否为根节点
    const isRoot = treeData.length > 0 && treeData[0].key === info.node.key;
    setIsRootNode(isRoot);
  };

  const handleAddSubmit = (res: any) => {
    if (res) {
      queryTreeList();
    }
  };

  useEffect(() => {
    queryTreeList();
  }, []);

  return (
    <div className={styles.treeWrap} ref={ref}>
      <div className={styles.treeTop}>
        <Input
          style={{ width: '95%', margin: '12px 8px' }}
          placeholder={intl.formatMessage({ id: 'siteManage.enterDeviceName' })}
          suffix={<SearchOutlined style={{ color: 'rgba(0,0,0,.45)' }} />}
          onChange={debounce(onChange, 300)}
          className={styles.tree_search}
        />
        <div className={styles.tree}>
          {treeData.length > 0 && (
            <Tree
              blockNode
              defaultSelectedKeys={[selectNodeID]}
              fieldNames={{ title: 'deviceName', key: 'key', children: 'subDevices' }}
              treeData={treeData}
              onSelect={TreeSelectMethod}
              titleRender={(data: TreeNode) => {
                return <div style={{ lineHeight: '32px' }}>{data.deviceName}</div>;
              }}
            />
          )}
        </div>
      </div>

      <div className={styles.treeBottom}>
        <AddModal
          handleAddSubmit={handleAddSubmit}
          areaId={selectNodeAreaId}
          isArea={isArea}
          isRoot={isRootNode}
          hasArea={hasArea}
          hasDevice={hasDevice}
          queryTreeList={queryTreeList}
        />
        <AddAreaModal
          handleAddSubmit={handleAddSubmit}
          isArea={isArea}
          treeSubDevices={treeSubDevices}
          hasArea={hasArea}
          hasDevice={hasDevice}
          queryTreeList={queryTreeList}
        />
        <Button
          type="primary"
          size="middle"
          danger
          onClick={DeleteTree}
          disabled={selectNodeID === '' || isRootNode}
        >
          {intl.formatMessage({ id: 'siteManage.del' })}
        </Button>
      </div>
    </div>
  );
});

export default TreeList;
